Python์ ์ ๊ตํ import hook ์์คํ ์ ์ดํด๋ณด์ธ์. ๋ชจ๋ ๋ก๋ฉ์ ๋ง์ถค ์ค์ ํ๊ณ , ์ฝ๋ ๊ตฌ์ฑ์ ๊ฐ์ ํ๋ฉฐ, ๊ธ๋ก๋ฒ Python ๊ฐ๋ฐ์ ์ํ ๋์ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์.
Python์ ์ ์ฌ๋ ฅ ๋ฐํ: Import Hook ์์คํ ์ฌ์ธต ๋ถ์
Python์ ๋ชจ๋ ์์คํ
์ ์ ์ฐ์ฑ๊ณผ ํ์ฅ์ฑ์ ์ด์์
๋๋ค. import some_module์ ์์ฑํ๋ฉด ๋ณต์กํ ํ๋ก์ธ์ค๊ฐ ๋ฌด๋ ๋ค์์ ํผ์ณ์ง๋๋ค. Python์ import ๋ฉ์ปค๋์ฆ์ ์ํด ๊ด๋ฆฌ๋๋ ์ด ํ๋ก์ธ์ค๋ฅผ ํตํด ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๋จ์๋ก ๊ตฌ์ฑํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด ๋ก๋ฉ ํ๋ก์ธ์ค๋ฅผ ๋ ๋ง์ด ์ ์ดํด์ผ ํ๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น์? ํน์ดํ ์์น์์ ๋ชจ๋์ ๋ก๋ํ๊ณ , ๋์ ์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํ๊ฑฐ๋, ์์ค ์ฝ๋๋ฅผ ์ํธํํ๊ณ ๋ฐํ์์ ํด๋
ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น์?
Python์ import hook ์์คํ ์ ์ดํด๋ณด์ธ์. ์ข ์ข ๊ฐ๊ณผ๋์ง๋ง ๊ฐ๋ ฅํ ์ด ๊ธฐ๋ฅ์ Python์ด ๋ชจ๋์ ์ฐพ๊ณ , ๋ก๋ํ๊ณ , ์คํํ๋ ๋ฐฉ์์ ๊ฐ๋ก์ฑ๊ณ ์ฌ์ฉ์ ์ ์ํ ์ ์๋ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ๋๊ท๋ชจ ํ๋ก์ ํธ, ๋ณต์กํ ํ๋ ์์ํฌ ๋๋ ๋ํดํ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์ ํ๋ ๊ฐ๋ฐ์์๊ฒ import hooks๋ฅผ ์ดํดํ๊ณ ํ์ฉํ๋ฉด ์๋นํ ์ฑ๋ฅ๊ณผ ์ ์ฐ์ฑ์ ์ป์ ์ ์์ต๋๋ค.
์ด ํฌ๊ด์ ์ธ ๊ฐ์ด๋์์๋ Python์ import hook ์์คํ ์ ๋ช ํํ๊ฒ ์ค๋ช ํฉ๋๋ค. ํต์ฌ ๊ตฌ์ฑ ์์๋ฅผ ์ดํด๋ณด๊ณ , ์ค์ ์ฌ๋ก๋ฅผ ํตํด ์ค์ฉ์ ์ธ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์์ฐํ๊ณ , ๊ฐ๋ฐ ์ํฌํ๋ก์ฐ์ ํตํฉํ๊ธฐ ์ํ ์คํ ๊ฐ๋ฅํ ํต์ฐฐ๋ ฅ์ ์ ๊ณตํฉ๋๋ค. ์ด ๊ฐ์ด๋๋ Python ๋ด๋ถ์ ๋ํด ๊ถ๊ธํ ์ด๋ณด์๋ถํฐ ๋ชจ๋ ๊ด๋ฆฌ์ ๋ํ ๊ฒฝ๊ณ๋ฅผ ๋ํ๋ ค๋ ์๋ จ๋ ์ ๋ฌธ๊ฐ๊น์ง, ๊ธ๋ก๋ฒ Python ๊ฐ๋ฐ์๋ฅผ ๋์์ผ๋ก ํฉ๋๋ค.
Python์ Import ํ๋ก์ธ์ค ํด๋ถ
Hook์ ์ดํด๋ณด๊ธฐ ์ ์ ํ์ค import ๋ฉ์ปค๋์ฆ์ ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. Python์ด import ๋ฌธ์ ๋ง๋๋ฉด ์ผ๋ จ์ ๋จ๊ณ๋ฅผ ๋ฐ๋ฆ
๋๋ค.
- ๋ชจ๋ ์ฐพ๊ธฐ: Python์ ํน์ ์์๋ก ๋ชจ๋์ ๊ฒ์ํฉ๋๋ค. ๋จผ์ ๋ด์ฅ ๋ชจ๋์ ํ์ธํ ๋ค์
sys.path์ ๋์ด๋ ๋๋ ํ ๋ฆฌ์์ ๋ชจ๋์ ์ฐพ์ต๋๋ค. ์ด ๋ชฉ๋ก์๋ ์ผ๋ฐ์ ์ผ๋ก ํ์ฌ ์คํฌ๋ฆฝํธ์ ๋๋ ํ ๋ฆฌ,PYTHONPATHํ๊ฒฝ ๋ณ์๋ก ์ง์ ๋ ๋๋ ํ ๋ฆฌ ๋ฐ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์น๊ฐ ํฌํจ๋ฉ๋๋ค. - ๋ชจ๋ ๋ก๋: ์ฐพ์ผ๋ฉด Python์ ๋ชจ๋์ ์์ค ์ฝ๋(๋๋ ์ปดํ์ผ๋ ๋ฐ์ดํธ์ฝ๋)๋ฅผ ์ฝ์ต๋๋ค.
- (ํ์ํ ๊ฒฝ์ฐ) ์ปดํ์ผ: ์์ค ์ฝ๋๊ฐ ์ด๋ฏธ ๋ฐ์ดํธ์ฝ๋(
.pycํ์ผ)๋ก ์ปดํ์ผ๋์ง ์์ ๊ฒฝ์ฐ ์ปดํ์ผ๋ฉ๋๋ค. - ๋ชจ๋ ์คํ: ๊ทธ๋ฐ ๋ค์ ์ปดํ์ผ๋ ์ฝ๋๋ ์ ๋ชจ๋ ๋ค์์คํ์ด์ค ๋ด์์ ์คํ๋ฉ๋๋ค.
- ๋ชจ๋ ์บ์ฑ: ๋ก๋๋ ๋ชจ๋ ๊ฐ์ฒด๋
sys.modules์ ์ ์ฅ๋๋ฏ๋ก ๋์ผํ ๋ชจ๋์ ํ์ import๋ ์บ์๋ ๊ฐ์ฒด๋ฅผ ๊ฒ์ํ์ฌ ์ค๋ณต ๋ก๋ ๋ฐ ์คํ์ ๋ฐฉ์งํฉ๋๋ค.
Python 3.1์ ๋์
๋ importlib ๋ชจ๋์ ์ด ํ๋ก์ธ์ค์ ๋ํ ๋ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ฉฐ import hooks๋ฅผ ๊ตฌํํ๊ธฐ ์ํ ๊ธฐ๋ฐ์
๋๋ค.
Import Hook ์์คํ ์๊ฐ
Import hook ์์คํ
์ ์ฌ์ฉํ๋ฉด import ํ๋ก์ธ์ค์ ํ๋ ์ด์์ ๋จ๊ณ๋ฅผ ๊ฐ๋ก์ฑ๊ณ ์์ ํ ์ ์์ต๋๋ค. ์ด๋ ์ฃผ๋ก sys.meta_path ๋ฐ sys.path_hooks ๋ชฉ๋ก์ ์กฐ์ํ์ฌ ์ํ๋ฉ๋๋ค. ์ด๋ฌํ ๋ชฉ๋ก์๋ ๋ชจ๋ ์ฐพ๊ธฐ ๋จ๊ณ์์ Python์ด ์ฐธ์กฐํ๋ finder ๊ฐ์ฒด๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
sys.meta_path: ์ฒซ ๋ฒ์งธ ๋ฐฉ์ด์
sys.meta_path๋ finder ๊ฐ์ฒด์ ๋ชฉ๋ก์
๋๋ค. import๊ฐ ์์๋๋ฉด Python์ ์ด๋ฌํ finder๋ฅผ ๋ฐ๋ณตํ๊ณ ํด๋น find_spec() ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค. find_spec() ๋ฉ์๋๋ ๋ชจ๋์ ์ฐพ์ ๋ชจ๋์ ๋ก๋ํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์ ๋ณด๋ฅผ ํฌํจํ๋ ModuleSpec ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ์ญํ ์ ํฉ๋๋ค.
ํ์ผ ๊ธฐ๋ฐ ๋ชจ๋์ ๊ธฐ๋ณธ finder๋ importlib.machinery.PathFinder์ด๋ฉฐ, sys.path๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋์ ์ฐพ์ต๋๋ค. ์์ฒด ์ฌ์ฉ์ ์ง์ finder ๊ฐ์ฒด๋ฅผ PathFinder ์์ sys.meta_path์ ์ฝ์
ํ๋ฉด import๋ฅผ ๊ฐ๋ก์ฑ์ finder๊ฐ ๋ชจ๋์ ์ฒ๋ฆฌํ ์ ์๋์ง ๊ฒฐ์ ํ ์ ์์ต๋๋ค.
sys.path_hooks: ๋๋ ํ ๋ฆฌ ๊ธฐ๋ฐ ๋ก๋ฉ์ ์ํ
sys.path_hooks๋ PathFinder์์ ์ฌ์ฉ๋๋ ํธ์ถ ๊ฐ๋ฅํ ๊ฐ์ฒด(hook)์ ๋ชฉ๋ก์
๋๋ค. ๊ฐ hook์๋ ๋๋ ํ ๋ฆฌ ๊ฒฝ๋ก๊ฐ ์ง์ ๋๋ฉฐ, ํด๋น ๊ฒฝ๋ก๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ ๊ฒฝ์ฐ(์: ํน์ ์ ํ์ ํจํค์ง ๊ฒฝ๋ก) ๋ก๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ๋ก๋ ๊ฐ์ฒด๋ ํด๋น ๋๋ ํ ๋ฆฌ ๋ด์์ ๋ชจ๋์ ์ฐพ๊ณ ๋ก๋ํ๋ ๋ฐฉ๋ฒ์ ์๊ณ ์์ต๋๋ค.
sys.meta_path๋ ๋ ์ผ๋ฐ์ ์ธ ์ ์ด๋ฅผ ์ ๊ณตํ๋ ๋ฐ๋ฉด, sys.path_hooks๋ ํน์ ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ ๋๋ ํจํค์ง ์ ํ์ ๋ํ ์ฌ์ฉ์ ์ง์ ๋ก๋ฉ ๋
ผ๋ฆฌ๋ฅผ ์ ์ํ๋ ค๋ ๊ฒฝ์ฐ์ ์ ์ฉํฉ๋๋ค.
์ฌ์ฉ์ ์ง์ Finder ๋ง๋ค๊ธฐ
Import hook์ ๊ตฌํํ๋ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ์ ์ฌ์ฉ์ ์ง์ finder ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ๊ฒ์
๋๋ค. ์ฌ์ฉ์ ์ง์ finder๋ find_spec(name, path, target=None) ๋ฉ์๋๋ฅผ ๊ตฌํํด์ผ ํฉ๋๋ค. ์ด ๋ฉ์๋๋ ๋ค์์ ์ํํฉ๋๋ค.
- ์์ : import ์ค์ธ ๋ชจ๋์ ์ด๋ฆ, ์์ ํจํค์ง ๊ฒฝ๋ก ๋ชฉ๋ก(ํ์ ๋ชจ๋์ธ ๊ฒฝ์ฐ) ๋ฐ ์ ํ์ ๋์ ๋ชจ๋ ๊ฐ์ฒด.
- ๋ฐํํด์ผ ํจ: ๋ชจ๋์ ์ฐพ์ ์ ์๋ ๊ฒฝ์ฐ
ModuleSpec๊ฐ์ฒด๋ฅผ ๋ฐํํ๊ณ , ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐNone์ ๋ฐํํด์ผ ํฉ๋๋ค.
ModuleSpec ๊ฐ์ฒด์๋ ๋ค์์ ํฌํจํ ์ค์ํ ์ ๋ณด๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
name: ๋ชจ๋์ ์ ๊ทํ๋ ์ด๋ฆ.loader: ๋ชจ๋์ ์ฝ๋๋ฅผ ๋ก๋ํ๋ ์ญํ ์ ๋ด๋นํ๋ ๊ฐ์ฒด.origin: ์์ค ํ์ผ ๋๋ ๋ฆฌ์์ค์ ๊ฒฝ๋ก.submodule_search_locations: ๋ชจ๋์ด ํจํค์ง์ธ ๊ฒฝ์ฐ ํ์ ๋ชจ๋์ ๊ฒ์ํ ๋๋ ํ ๋ฆฌ ๋ชฉ๋ก.
์: ์๊ฒฉ URL์์ ๋ชจ๋ ๋ก๋ํ๊ธฐ
์น ์๋ฒ์์ ์ง์ Python ๋ชจ๋์ ๋ก๋ํ๋ ค๋ ์๋๋ฆฌ์ค๋ฅผ ์์ํด ๋ณด๊ฒ ์ต๋๋ค. ์ด๋ ์ ๋ฐ์ดํธ๋ฅผ ๋ฐฐํฌํ๊ฑฐ๋ ์ค์ ์ง์ค์ ๊ตฌ์ฑ ์์คํ ์ ์ ์ฉํ ์ ์์ต๋๋ค.
๋ชจ๋์ด ๋ก์ปฌ์์ ๋ฐ๊ฒฌ๋์ง ์์ผ๋ฉด ๋ฏธ๋ฆฌ ์ ์๋ URL ๋ชฉ๋ก์ ํ์ธํ๋ ์ฌ์ฉ์ ์ง์ finder๋ฅผ ๋ง๋ค ๊ฒ์ ๋๋ค.
import sys
import importlib.abc
import importlib.util
import urllib.request
class UrlFinder(importlib.abc.MetaPathFinder):
def __init__(self, base_urls):
self.base_urls = base_urls
def find_spec(self, fullname, path, target=None):
# Construct potential module paths
for url in self.base_urls:
module_url = f"{url}/{fullname.replace('.', '/')}.py"
try:
# Attempt to open the URL to see if the file exists
with urllib.request.urlopen(module_url, timeout=1) as response:
if response.getcode() == 200:
# If found, create a ModuleSpec
spec = importlib.util.spec_from_loader(
fullname,
RemoteFileLoader(fullname, module_url)
)
return spec
except urllib.error.URLError:
# Ignore errors, try next URL or move on
pass
return None # Module not found by this finder
class RemoteFileLoader(importlib.abc.Loader):
def __init__(self, fullname, url):
self.fullname = fullname
self.url = url
def get_filename(self, fullname):
# This might not be strictly necessary but good practice
return self.url
def get_data(self, filename):
# Fetch the source code from the URL
try:
with urllib.request.urlopen(self.url, timeout=5) as response:
return response.read()
except urllib.error.URLError as e:
raise ImportError(f"Failed to fetch {self.url}: {e}") from e
def create_module(self, spec):
# For Python 3.5+, we can create the module object directly
return None # Returning None tells importlib to create it using the spec
def exec_module(self, module):
# Load and execute the module code
source = self.get_data(self.url).decode('utf-8')
exec(source, module.__dict__)
# --- Usage ---
# Define the base URLs where modules might be found
remote_urls = ["http://my-python-modules.com/v1", "http://backup.modules.net/v1"]
# Create an instance of our custom finder
url_finder = UrlFinder(remote_urls)
# Insert our finder at the beginning of sys.meta_path
sys.meta_path.insert(0, url_finder)
# Now, if 'my_remote_module' exists at one of the URLs, it will be loaded
# import my_remote_module
# print(my_remote_module.hello())
# To clean up after testing:
# sys.meta_path.remove(url_finder)
์ค๋ช :
UrlFinder๋ ๋ฉํ ๊ฒฝ๋ก finder ์ญํ ์ ํฉ๋๋ค. ์ ๊ณต๋base_urls๋ฅผ ๋ฐ๋ณตํฉ๋๋ค.- ๊ฐ URL์ ๋ํด ๋ชจ๋ ํ์ผ์ ๋ํ ์ ์ฌ์ ๊ฒฝ๋ก๋ฅผ ๊ตฌ์ฑํฉ๋๋ค(์:
http://my-python-modules.com/v1/my_remote_module.py). urllib.request.urlopen์ ์ฌ์ฉํ์ฌ ํ์ผ์ด ์๋์ง ํ์ธํฉ๋๋ค.- ๋ฐ๊ฒฌ๋๋ฉด ์ฌ์ฉ์ ์ง์
RemoteFileLoader์ ์ฐ๊ฒฐํ์ฌModuleSpec์ ๋ง๋ญ๋๋ค. RemoteFileLoader๋ URL์์ ์์ค ์ฝ๋๋ฅผ ๊ฐ์ ธ์ ๋ชจ๋์ ๋ค์์คํ์ด์ค ๋ด์์ ์คํํ๋ ์ญํ ์ ํฉ๋๋ค.
๊ธ๋ก๋ฒ ๊ณ ๋ ค ์ฌํญ: ์๊ฒฉ ๋ชจ๋์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋คํธ์ํฌ ์์ ์ฑ, ๋๊ธฐ ์๊ฐ ๋ฐ ๋ณด์์ด ๊ฐ์ฅ ์ค์ํด์ง๋๋ค. ์บ์ฑ, ๋์ฒด ๋ฉ์ปค๋์ฆ ๋ฐ ๊ฐ๋ ฅํ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค. ๊ตญ์ ๋ฐฐํฌ์ ๊ฒฝ์ฐ ์๊ฒฉ ์๋ฒ๊ฐ ์ ์ธ๊ณ ์ฌ์ฉ์์ ๋๊ธฐ ์๊ฐ์ ์ต์ํํ๊ธฐ ์ํด ์ง๋ฆฌ์ ์ผ๋ก ๋ถ์ฐ๋์ด ์๋์ง ํ์ธํ์ญ์์ค.
์: ๋ชจ๋ ์ํธํ ๋ฐ ํด๋
์ง์ ์ฌ์ฐ ๋ณดํธ ๋๋ ํฅ์๋ ๋ณด์์ ์ํด ์ํธํ๋ Python ๋ชจ๋์ ๋ฐฐํฌํ ์ ์์ต๋๋ค. ์ฌ์ฉ์ ์ง์ hook์ ์คํ ์ง์ ์ ์ฝ๋๋ฅผ ํด๋ ํ ์ ์์ต๋๋ค.
import sys
import importlib.abc
import importlib.util
import base64
# Assume a simple XOR encryption for demonstration
def encrypt_decrypt(data, key):
key_len = len(key)
return bytes(data[i] ^ key[i % key_len] for i in range(len(data)))
ENCRYPTION_KEY = b"your_secret_key_here"
class EncryptedFileLoader(importlib.abc.Loader):
def __init__(self, fullname, filename):
self.fullname = fullname
self.filename = filename
def get_filename(self, fullname):
return self.filename
def get_data(self, filename):
with open(filename, 'rb') as f:
encrypted_data = f.read()
return encrypt_decrypt(encrypted_data, ENCRYPTION_KEY)
def create_module(self, spec):
# For Python 3.5+, returning None delegates module creation to importlib
return None
def exec_module(self, module):
source = self.get_data(self.filename).decode('utf-8')
exec(source, module.__dict__)
class EncryptedFinder(importlib.abc.MetaPathFinder):
def __init__(self, module_dir):
self.module_dir = module_dir
# Preload modules that are encrypted
self.encrypted_modules = {}
import os
for filename in os.listdir(module_dir):
if filename.endswith(".enc"):
module_name = filename[:-4] # Remove .enc extension
self.encrypted_modules[module_name] = os.path.join(module_dir, filename)
def find_spec(self, fullname, path, target=None):
if fullname in self.encrypted_modules:
module_path = self.encrypted_modules[fullname]
spec = importlib.util.spec_from_loader(
fullname,
EncryptedFileLoader(fullname, module_path),
origin=module_path
)
return spec
return None
# --- Usage ---
# Assume 'my_secret_module.py' was encrypted using ENCRYPTION_KEY and saved as 'my_secret_module.enc'
# You would distribute 'my_secret_module.enc' and this loader/finder.
# Example: Create a dummy encrypted file for testing
# with open("my_secret_module.py", "w") as f:
# f.write("def greet(): return 'Hello from the secret module!'")
# with open("my_secret_module.py", "rb") as f_in, open("my_secret_module.enc", "wb") as f_out:
# data = f_in.read()
# f_out.write(encrypt_decrypt(data, ENCRYPTION_KEY))
# Create a directory for encrypted modules (e.g., 'encrypted_modules')
# and place 'my_secret_module.enc' inside.
# encrypted_dir = "./encrypted_modules"
# encrypted_finder = EncryptedFinder(encrypted_dir)
# sys.meta_path.insert(0, encrypted_finder)
# Now, import the module - the hook will decrypt it automatically
# import my_secret_module
# print(my_secret_module.greet())
# To clean up:
# sys.meta_path.remove(encrypted_finder)
# os.remove("my_secret_module.enc") # and the original .py if created for testing
์ค๋ช :
EncryptedFinder๋.enc๋ก ๋๋๋ ํ์ผ์ ์ํด ์ฃผ์ด์ง ๋๋ ํ ๋ฆฌ๋ฅผ ์ค์บํฉ๋๋ค.- ๋ชจ๋ ์ด๋ฆ์ด ์ํธํ๋ ํ์ผ๊ณผ ์ผ์นํ๋ฉด
EncryptedFileLoader๋ฅผ ์ฌ์ฉํ์ฌModuleSpec์ ๋ฐํํฉ๋๋ค. EncryptedFileLoader๋ ์ํธํ๋ ํ์ผ์ ์ฝ๊ณ , ์ ๊ณต๋ ํค๋ฅผ ์ฌ์ฉํ์ฌ ํด๋น ๋ด์ฉ์ ํด๋ ํ ๋ค์ ์ผ๋ฐ ํ ์คํธ ์์ค ์ฝ๋๋ฅผ ๋ฐํํฉ๋๋ค.exec_module์ ์ด ํด๋ ๋ ์์ค๋ฅผ ์คํํฉ๋๋ค.
๋ณด์ ์ฐธ๊ณ ์ฌํญ: ์ด๋ ๋จ์ํ๋ ์์ ๋๋ค. ์ค์ ์ํธํ์๋ ๋ ๊ฐ๋ ฅํ ์๊ณ ๋ฆฌ์ฆ๊ณผ ํค ๊ด๋ฆฌ๊ฐ ํฌํจ๋ฉ๋๋ค. ํค ์์ฒด๋ ์์ ํ๊ฒ ์ ์ฅ๋๊ฑฐ๋ ํ์๋์ด์ผ ํฉ๋๋ค. ์ฝ๋์ ํจ๊ป ํค๋ฅผ ๋ฐฐํฌํ๋ฉด ์ํธํ ๋ชฉ์ ์ ๋๋ถ๋ถ์ด ๋ฌดํจํ๋ฉ๋๋ค.
Loader๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋ ์คํ ์ฌ์ฉ์ ์ง์
Finder๊ฐ ๋ชจ๋์ ์ฐพ๋ ๋์ ๋ก๋๋ ์ค์ ๋ก๋ฉ ๋ฐ ์คํ์ ๋ด๋นํฉ๋๋ค. importlib.abc.Loader ์ถ์ ๊ธฐ๋ณธ ํด๋์ค๋ ๋ก๋๊ฐ ๊ตฌํํด์ผ ํ๋ ๋ฉ์๋๋ฅผ ์ ์ํฉ๋๋ค. ์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
create_module(spec): ๋น ๋ชจ๋ ๊ฐ์ฒด๋ฅผ ๋ง๋ญ๋๋ค. Python 3.5+์์ ์ฌ๊ธฐ์None์ ๋ฐํํ๋ฉดimportlib์ดModuleSpec์ ์ฌ์ฉํ์ฌ ๋ชจ๋์ ๋ง๋ค๋๋ก ์ง์ํฉ๋๋ค.exec_module(module): ์ง์ ๋ ๋ชจ๋ ๊ฐ์ฒด ๋ด์์ ๋ชจ๋์ ์ฝ๋๋ฅผ ์คํํฉ๋๋ค.
finder์ find_spec ๋ฉ์๋๋ loader๋ฅผ ํฌํจํ๋ ModuleSpec์ ๋ฐํํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ด ๋ก๋๋ importlib์์ ์คํ์ ์ํํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
Hooks ๋ฑ๋ก ๋ฐ ๊ด๋ฆฌ
์ฌ์ฉ์ ์ง์ finder๋ฅผ sys.meta_path์ ์ถ๊ฐํ๋ ๊ฒ์ ๊ฐ๋จํฉ๋๋ค.
import sys
# Assuming CustomFinder is your implemented finder class
my_finder = CustomFinder(...)
sys.meta_path.insert(0, my_finder) # Insert at the beginning to give it priority
๊ด๋ฆฌ ๋ชจ๋ฒ ์ฌ๋ก:
- ์ฐ์ ์์: finder๋ฅผ
sys.meta_path์ ์์ธ 0์ ์ฝ์ ํ๋ฉด ๊ธฐ๋ณธPathFinder๋ฅผ ํฌํจํ์ฌ ๋ค๋ฅธ finder๋ณด๋ค ๋จผ์ ํ์ธ๋ฉ๋๋ค. ์ด๋ hook์ด ํ์ค ๋ก๋ฉ ๋์์ ์ฌ์ ์ํ๋ ค๋ ๊ฒฝ์ฐ์ ์ค์ํฉ๋๋ค. - ์์๊ฐ ์ค์ํฉ๋๋ค: ์ฌ๋ฌ ์ฌ์ฉ์ ์ง์ finder๊ฐ ์๋ ๊ฒฝ์ฐ
sys.meta_path์์ ํด๋น ์์๊ฐ ์กฐํ ์ํ์ค๋ฅผ ๊ฒฐ์ ํฉ๋๋ค. - ์ ๋ฆฌ: ํ
์คํธ ์ค์ด๊ฑฐ๋ ์ ํ๋ฆฌ์ผ์ด์
์ข
๋ฃ ์ค์ ์๋ํ์ง ์์ ๋ถ์์ฉ์ ๋ฐฉ์งํ๋ ค๋ฉด ์ฌ์ฉ์ ์ง์ finder๋ฅผ
sys.meta_path์์ ์ ๊ฑฐํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
sys.path_hooks๋ ๋น์ทํ๊ฒ ์๋ํฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ๊ฒฝ๋ก ํญ๋ชฉ hook์ ์ด ๋ชฉ๋ก์ ์ฝ์
ํ์ฌ sys.path์ ํน์ ์ ํ์ ๊ฒฝ๋ก๊ฐ ํด์๋๋ ๋ฐฉ์์ ์ฌ์ฉ์ ์ง์ ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์๊ฒฉ ์์นด์ด๋ธ(์: zip ํ์ผ)๋ฅผ ๊ฐ๋ฆฌํค๋ ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉ์ ์ง์ ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌํ๋ hook์ ๋ง๋ค ์ ์์ต๋๋ค.
๊ณ ๊ธ ์ฌ์ฉ ์ฌ๋ก ๋ฐ ๊ณ ๋ ค ์ฌํญ
Import hook ์์คํ ์ ๊ด๋ฒ์ํ ๊ณ ๊ธ ํ๋ก๊ทธ๋๋ฐ ํจ๋ฌ๋ค์์ผ๋ก ๊ฐ๋ ๋ฌธ์ ์ฝ๋๋ค.
1. Hot Code Swapping ๋ฐ ์ฌ๋ก๋ฉ
์ค๋ ์คํ๋๋ ์ ํ๋ฆฌ์ผ์ด์
(์: ์๋ฒ, ์๋ฒ ๋๋ ์์คํ
)์์ ๋ค์ ์์ํ์ง ์๊ณ ์ฝ๋๋ฅผ ์
๋ฐ์ดํธํ๋ ๊ธฐ๋ฅ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ํ์ค importlib.reload()์ด ์กด์ฌํ์ง๋ง, ์ฌ์ฉ์ ์ง์ hook์ import ํ๋ก์ธ์ค ์์ฒด๋ฅผ ๊ฐ๋ก์ฑ์ ์ข
์์ฑ ๋ฐ ์ํ๋ฅผ ๋ ์ธ๋ถํํ์ฌ ๊ด๋ฆฌํ์ฌ ๋ณด๋ค ์ ๊ตํ ํซ ์ค์ํ์ ๊ฐ๋ฅํ๊ฒ ํ ์ ์์ต๋๋ค.
2. ๋ฉํ ํ๋ก๊ทธ๋๋ฐ ๋ฐ ์ฝ๋ ์์ฑ
import hook์ ์ฌ์ฉํ์ฌ ๋ก๋๋๊ธฐ ์ ์ Python ์ฝ๋๋ฅผ ๋์ ์ผ๋ก ์์ฑํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ๋ฐํ์ ์กฐ๊ฑด, ๊ตฌ์ฑ ํ์ผ ๋๋ ์ธ๋ถ ๋ฐ์ดํฐ ์์ค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ณ ๋๋ก ์ฌ์ฉ์ ์ง์ ๋ ๋ชจ๋์ ๋ง๋ค ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๊ทธ ๋ด์ฑ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก C ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ํํ๋ ๋ชจ๋์ ์์ฑํ ์ ์์ต๋๋ค.
3. ์ฌ์ฉ์ ์ง์ ํจํค์ง ํ์
ํ์ค Python ํจํค์ง ๋ฐ zip ์์นด์ด๋ธ ์ธ์๋ ๋ชจ๋์ ํจํค์งํ๊ณ ๋ฐฐํฌํ๋ ์์ ํ ์๋ก์ด ๋ฐฉ๋ฒ์ ์ ์ํ ์ ์์ต๋๋ค. ์ฌ๊ธฐ์๋ ์ฌ์ฉ์ ์ง์ ์์นด์ด๋ธ ํ์, ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ธฐ๋ฐ ๋ชจ๋ ๋๋ ๋๋ฉ์ธ๋ณ ์ธ์ด(DSL)์์ ์์ฑ๋ ๋ชจ๋์ด ํฌํจ๋ ์ ์์ต๋๋ค.
4. ์ฑ๋ฅ ์ต์ ํ
์ฑ๋ฅ์ด ์ค์ํ ์๋๋ฆฌ์ค์์๋ hook์ ์ฌ์ฉํ์ฌ ๋ฏธ๋ฆฌ ์ปดํ์ผ๋ ๋ชจ๋(์: C ํ์ฅ)์ ๋ก๋ํ๊ฑฐ๋ ์๋ ค์ง ์์ ํ ๋ชจ๋์ ๋ํ ํน์ ๊ฒ์ฌ๋ฅผ ์ฐํํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ import ํ๋ก์ธ์ค ์์ฒด์ ์๋นํ ์ค๋ฒํค๋๊ฐ ๋์ ๋์ง ์๋๋ก ์ฃผ์ํด์ผ ํฉ๋๋ค.
5. ์๋๋ฐ์ฑ ๋ฐ ๋ณด์
Import hook์ ์ฌ์ฉํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ํน์ ๋ถ๋ถ์์ ๊ฐ์ ธ์ฌ ์ ์๋ ๋ชจ๋์ ์ ์ดํ ์ ์์ต๋๋ค. ๋ฏธ๋ฆฌ ์ ์๋ ๋ชจ๋ ์ธํธ๋ง ์ฌ์ฉํ ์ ์๋ ์ ํ๋ ํ๊ฒฝ์ ๋ง๋ค์ด ์ ๋ขฐํ ์ ์๋ ์ฝ๋๊ฐ ๋ฏผ๊ฐํ ์์คํ ๋ฆฌ์์ค์ ์ก์ธ์คํ๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
๊ณ ๊ธ ์ฌ์ฉ ์ฌ๋ก์ ๋ํ ๊ธ๋ก๋ฒ ๊ด์ :
- ๊ตญ์ ํ(i18n) ๋ฐ ํ์งํ(l10n): ์ฌ์ฉ์ ๋ก์บ์ ๊ธฐ๋ฐ์ผ๋ก ์ธ์ด๋ณ ๋ชจ๋์ ๋์ ์ผ๋ก ๋ก๋ํ๋ ํ๋ ์์ํฌ๋ฅผ ์์ํด ๋ณด์ญ์์ค. Import hook์ ๋ฒ์ญ ๋ชจ๋์ ๋ํ ์์ฒญ์ ๊ฐ๋ก์ฑ ์ฌ๋ฐ๋ฅธ ์ธ์ด ํฉ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
- ํ๋ซํผ๋ณ ์ฝ๋: Python์
sys.platform์ ์ผ๋ถ ํ๋ซํผ ๊ฐ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ง๋ง, ๋ ๋ฐ์ ๋ ์์คํ ์ import hooks๋ฅผ ์ฌ์ฉํ์ฌ ์ด์ ์ฒด์ , ์ํคํ ์ฒ ๋๋ ๊ธ๋ก๋ฒํ๊ฒ ์ฌ์ฉ ๊ฐ๋ฅํ ํน์ ํ๋์จ์ด ๊ธฐ๋ฅ์ ๊ธฐ๋ฐ์ผ๋ก ๋ชจ๋์ ์์ ํ ๋ค๋ฅธ ๊ตฌํ์ ๋ก๋ํ ์ ์์ต๋๋ค. - ๋ถ์ฐ ์์คํ : ๋ถ์ฐ ์ ํ๋ฆฌ์ผ์ด์ (์: ๋ธ๋ก์ฒด์ธ ๋๋ P2P ๋คํธ์ํฌ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ถ๋ ์ ํ๋ฆฌ์ผ์ด์ )์์ import hooks๋ ์ค์ ์๋ฒ๊ฐ ์๋ ๋ถ์ฐ ์์ค์์ ๋ชจ๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ์ ๋ณต์๋ ฅ๊ณผ ๊ฒ์ด ์ ํญ์ฑ์ ํฅ์์ํฌ ์ ์์ต๋๋ค.
์ ์ฌ์ ์ธ ์ํ ์์ ๋ฐ ์ด๋ฅผ ๋ฐฉ์งํ๋ ๋ฐฉ๋ฒ
๊ฐ๋ ฅํ์ง๋ง import hook์ ์ฃผ์ํด์ ์ฌ์ฉํ์ง ์์ผ๋ฉด ๋ณต์ก์ฑ๊ณผ ์์์น ๋ชปํ ๋์์ด ๋ฐ์ํ ์ ์์ต๋๋ค.
- ๋๋ฒ๊น ์ด๋ ค์: ์ฌ์ฉ์ ์ง์ import hook์ ํฌ๊ฒ ์์กดํ๋ ์ฝ๋๋ฅผ ๋๋ฒ๊น ํ๋ ๊ฒ์ ์ด๋ ค์ธ ์ ์์ต๋๋ค. ํ์ค ๋๋ฒ๊น ๋๊ตฌ๋ ์ฌ์ฉ์ ์ง์ ๋ก๋ฉ ํ๋ก์ธ์ค๋ฅผ ์์ ํ ์ดํดํ์ง ๋ชปํ ์ ์์ต๋๋ค. hook์์ ๋ช ํํ ์ค๋ฅ ๋ฉ์์ง์ ๋ก๊น ์ ์ ๊ณตํ๋์ง ํ์ธํ์ญ์์ค.
- ์ฑ๋ฅ ์ค๋ฒํค๋: ๊ฐ ์ฌ์ฉ์ ์ง์ hook์ import ํ๋ก์ธ์ค์ ๋จ๊ณ๋ฅผ ์ถ๊ฐํฉ๋๋ค. hook์ด ๋นํจ์จ์ ์ด๊ฑฐ๋ ๋น์ฉ์ด ๋ง์ด ๋๋ ์์ ์ ์ํํ๋ ๊ฒฝ์ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ ์๊ฐ์ด ํฌ๊ฒ ์ฆ๊ฐํ ์ ์์ต๋๋ค. hook ๋ ผ๋ฆฌ๋ฅผ ์ต์ ํํ๊ณ ์บ์ฑ ๊ฒฐ๊ณผ๋ฅผ ๊ณ ๋ คํ์ญ์์ค.
- ์ข ์์ฑ ์ถฉ๋: ์ฌ์ฉ์ ์ง์ ๋ก๋๋ ๋ค๋ฅธ ํจํค์ง์์ ๋ชจ๋์ ๋ก๋ํ๋ ๋ฐฉ์๊ณผ ์ถฉ๋ํ์ฌ ๋ฏธ๋ฌํ ์ข ์์ฑ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์์ต๋๋ค. ๋ค์ํ ์๋๋ฆฌ์ค์์ ์ฒ ์ ํ ํ ์คํธ๊ฐ ํ์์ ์ ๋๋ค.
- ๋ณด์ ์ํ: ์ํธํ ์์ ์์ ๋ณผ ์ ์๋ฏ์ด ์ฌ์ฉ์ ์ง์ hook์ ๋ณด์์ ์ฌ์ฉ๋ ์ ์์ง๋ง, ์ ๋๋ก ๊ตฌํ๋์ง ์์ผ๋ฉด ์ ์ฉ๋ ์๋ ์์ต๋๋ค. ์ ์ฑ ์ฝ๋๋ ์์ ํ์ง ์์ hook์ ์ ๋ณตํ์ฌ ์ ์ฌ์ ์ผ๋ก ์์ฒด์ ์ผ๋ก ์ฝ์ ํ ์ ์์ต๋๋ค. ์ธ๋ถ ์ฝ๋์ ๋ฐ์ดํฐ๋ฅผ ํญ์ ์๊ฒฉํ๊ฒ ๊ฒ์ฆํ์ญ์์ค.
- ๊ฐ๋ ์ฑ ๋ฐ ์ ์ง ๊ด๋ฆฌ์ฑ: ๊ณผ๋ํ ์ฌ์ฉ ๋๋ ์ง๋์น๊ฒ ๋ณต์กํ import hook ๋ ผ๋ฆฌ๋ ๋ค๋ฅธ ์ฌ๋(๋๋ ๋ฏธ๋์ ์์ )์ด ์ฝ๋๋ฒ ์ด์ค๋ฅผ ์ดํดํ๊ณ ์ ์ง ๊ด๋ฆฌํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ค ์ ์์ต๋๋ค. hook์ ๊ด๋ฒ์ํ๊ฒ ๋ฌธ์ํํ๊ณ ํด๋น ๋ ผ๋ฆฌ๋ฅผ ๊ฐ๋ฅํ ํ ๊ฐ๋จํ๊ฒ ์ ์งํ์ญ์์ค.
์ํ ์์ ๋ฐฉ์ง๋ฅผ ์ํ ๊ธ๋ก๋ฒ ๋ชจ๋ฒ ์ฌ๋ก:
- ํ์คํ: ๊ธ๋ก๋ฒ ์ ์ฌ ๊ณ ๊ฐ์ ์ํด ์ฌ์ฉ์ ์ง์ hook์ ์์กดํ๋ ์์คํ ์ ๊ตฌ์ถํ ๋ ํ์ค์ ์ํด ๋ ธ๋ ฅํฉ๋๋ค. ์ ํจํค์ง ํ์์ ์ ์ํ๋ ๊ฒฝ์ฐ ๋ช ํํ๊ฒ ๋ฌธ์ํํ์ญ์์ค. ๊ฐ๋ฅํ ๊ฒฝ์ฐ ๊ธฐ์กด Python ํจํค์ง ํ์ค์ ์ค์ํ์ญ์์ค.
- ๋ช ํํ ๋ฌธ์ํ: ์ฌ์ฉ์ ์ง์ import hook์ด ํฌํจ๋ ๋ชจ๋ ํ๋ก์ ํธ์ ๊ฒฝ์ฐ ํฌ๊ด์ ์ธ ๋ฌธ์๋ ํ์ํ ์ ์์ต๋๋ค. ๊ฐ hook์ ๋ชฉ์ , ์์ ๋์ ๋ฐ ๋ชจ๋ ํ์ ์กฐ๊ฑด์ ์ค๋ช ํ์ญ์์ค. ์ด๋ ์์ฌ ์ํต์ด ๋ค๋ฅธ ์๊ฐ๋์ ๋ฌธํ์ ๋์์ค๋ฅผ ํฌํจํ ์ ์๋ ๊ตญ์ ํ์ ๊ฒฝ์ฐ ํนํ ์ค์ํฉ๋๋ค.
- ํ
์คํ
ํ๋ ์์ํฌ: Python์ ํ
์คํ
ํ๋ ์์ํฌ(์:
unittest๋๋pytest)๋ฅผ ํ์ฉํ์ฌ import hook์ ๋ํ ๊ฐ๋ ฅํ ํ ์คํธ ์ ํ๊ตฐ์ ๋ง๋ญ๋๋ค. ์ค๋ฅ ์กฐ๊ฑด, ๋ค์ํ ๋ชจ๋ ์ ํ ๋ฐ ์ฃ์ง ์ผ์ด์ค๋ฅผ ํฌํจํ ๋ค์ํ ์๋๋ฆฌ์ค๋ฅผ ํ ์คํธํฉ๋๋ค.
ํ๋ Python์์ importlib์ ์ญํ
importlib ๋ชจ๋์ Python์ import ์์คํ
๊ณผ ์ํธ ์์ฉํ๋ ํ๋์ ์ด๊ณ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ ๋ฐฉ๋ฒ์
๋๋ค. ๋ค์์ ์ํํ๋ ํด๋์ค ๋ฐ ํจ์๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ๋ชจ๋ ๊ฒ์ฌ: ๋ก๋๋ ๋ชจ๋์ ๋ํ ์ ๋ณด๋ฅผ ์ป์ต๋๋ค.
- ๋ชจ๋ ์์ฑ ๋ฐ ๋ก๋: ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก ๋ชจ๋์ importํ๊ฑฐ๋ ์์ฑํฉ๋๋ค.
- import ํ๋ก์ธ์ค ์ฌ์ฉ์ ์ง์ : ์ด๋
importlib.abc๋ฐimportlib.util์ ์ฌ์ฉํ์ฌ ๊ตฌ์ถ๋ finder ๋ฐ loader๊ฐ ์๋ํ๋ ๊ณณ์ ๋๋ค.
importlib์ ์ดํดํ๋ ๊ฒ์ import hook ์์คํ
์ ํจ๊ณผ์ ์ผ๋ก ์ฌ์ฉํ๊ณ ํ์ฅํ๋ ๋ฐ ํต์ฌ์
๋๋ค. ์ค๊ณ๋ ๋ช
ํ์ฑ๊ณผ ํ์ฅ์ฑ์ ์ฐ์ ์ํ๋ฏ๋ก Python 3์์ ์ฌ์ฉ์ ์ง์ import ๋
ผ๋ฆฌ์ ๊ถ์ฅ๋๋ ์ ๊ทผ ๋ฐฉ์์
๋๋ค.
๊ฒฐ๋ก
Python์ import hook ์์คํ ์ ๊ฐ๋ฐ์์๊ฒ ๋ชจ๋์ ๊ฒ์, ๋ก๋ ๋ฐ ์คํํ๋ ๋ฐฉ์์ ๋ํ ์ธ๋ถํ๋ ์ ์ด๋ฅผ ์ ๊ณตํ๋ ๊ฐ๋ ฅํ์ง๋ง ์ข ์ข ํ์ฉ๋์ง ์๋ ๊ธฐ๋ฅ์ ๋๋ค.
์๊ฒฉ ์๋ฒ์์ ๋ชจ๋์ ๋ก๋ํ๊ณ ์ํธํ๋ฅผ ํตํด ์ง์ ์ฌ์ฐ์ ๋ณดํธํ๋ ๊ฒ๋ถํฐ ํซ ์ฝ๋ ์ค์ํ์ ํ์ฑํํ๊ณ ์์ ํ ์๋ก์ด ํจํค์ง ํ์์ ๋ง๋๋ ๊ฒ๊น์ง, ๊ฐ๋ฅ์ฑ์ ๊ด๋ํฉ๋๋ค. ๊ธ๋ก๋ฒ Python ๊ฐ๋ฐ ์ปค๋ฎค๋ํฐ์ ๊ฒฝ์ฐ ์ด๋ฌํ ๊ณ ๊ธ import ๋ฉ์ปค๋์ฆ์ ์๋ฌํ๋ฉด ๋ณด๋ค ๊ฐ๋ ฅํ๊ณ ์ ์ฐํ๋ฉฐ ํ์ ์ ์ธ ์ํํธ์จ์ด ์๋ฃจ์ ์ ๋ง๋ค ์ ์์ต๋๋ค. Python์ import hook ์์คํ ์ ๋ชจ๋ ์ ์ฌ๋ ฅ์ ํ์ฉํ๋ ค๋ฉด ๋ช ํํ ๋ฌธ์ํ, ์ฒ ์ ํ ํ ์คํธ ๋ฐ ๋ณต์ก์ฑ์ ๋ํ ์ฃผ์ ๊น์ ์ ๊ทผ ๋ฐฉ์์ ์ฐ์ ์ ์ผ๋ก ๊ณ ๋ คํ์ญ์์ค.
Python์ import ๋์์ ์ฌ์ฉ์ ์ง์ ํ๋ ๋ฐ ์ฐฉ์ํ ๋ ์ ํ ์ฌํญ์ ๋ํ ๊ธ๋ก๋ฒ ์ํฅ์ ๊ณ ๋ คํ์ญ์์ค. ํจ์จ์ ์ด๊ณ ์์ ํ๋ฉฐ ์ ๋ฌธ์ํ๋ import hook์ ๋ค์ํ ๊ตญ์ ํ๊ฒฝ์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐ ๋ฐ ๋ฐฐํฌ๋ฅผ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค.